diff --git a/ryu/common.h b/ryu/common.h
index 7dc1309..41a43aa 100644
--- a/ryu/common.h
+++ b/ryu/common.h
@@ -85,18 +85,18 @@ static inline uint32_t log10Pow5(const int32_t e) {
 
 static inline int copy_special_str(char * const result, const bool sign, const bool exponent, const bool mantissa) {
   if (mantissa) {
-    memcpy(result, "NaN", 3);
+    memcpy(result, "nan", 3);
     return 3;
   }
   if (sign) {
     result[0] = '-';
   }
   if (exponent) {
-    memcpy(result + sign, "Infinity", 8);
-    return sign + 8;
+    memcpy(result + sign, "inf", 3);
+    return sign + 3;
   }
-  memcpy(result + sign, "0E0", 3);
-  return sign + 3;
+  memcpy(result + sign, "0", 1);
+  return sign + 1;
 }
 
 static inline uint32_t float_to_bits(const float f) {
diff --git a/ryu/d2s.c b/ryu/d2s.c
index aa0da52..33919be 100644
--- a/ryu/d2s.c
+++ b/ryu/d2s.c
@@ -327,6 +327,53 @@ static inline int to_chars(const floating_decimal_64 v, const bool sign, char* c
   printf("EXP=%u\n", v.exponent + olength);
 #endif
 
+  /// Plain format without exponent
+  int32_t exp = v.exponent + (int32_t) olength - 1;
+  if (exp >= -4 && exp <= 15) {
+    if (exp < 0) {
+      result[index++] = '0';
+      result[index++] = '.';
+
+      while (++exp) {
+        result[index++] = '0';
+      }
+
+      for (int32_t i = olength - 1; i >= 0; --i) {
+        const uint32_t c = output % 10;
+        output /= 10;
+        result[index + i] = '0' + c;
+      }
+      index += olength;
+    } else if (exp + 1 >= olength) {
+      for (int32_t i = olength - 1; i >= 0; --i) {
+        const uint32_t c = output % 10;
+        output /= 10;
+        result[index + i] = '0' + c;
+      }
+      index += olength;
+
+      while (exp >= olength) {
+        result[index++] = '0';
+        --exp;
+      }
+    } else {
+      for (int32_t i = olength; i > exp + 1; --i) {
+        const uint32_t c = output % 10;
+        output /= 10;
+        result[index + i] = '0' + c;
+      }
+      result[index + exp + 1] = '.';
+      for (int32_t i = exp; i >= 0; --i) {
+        const uint32_t c = output % 10;
+        output /= 10;
+        result[index + i] = '0' + c;
+      }
+      index += olength + 1;
+    }
+
+    return index;
+  }
+
   // Print the decimal digits.
   // The following code is equivalent to:
   // for (uint32_t i = 0; i < olength - 1; ++i) {
@@ -397,11 +444,12 @@ static inline int to_chars(const floating_decimal_64 v, const bool sign, char* c
   }
 
   // Print the exponent.
-  result[index++] = 'E';
-  int32_t exp = v.exponent + (int32_t) olength - 1;
+  result[index++] = 'e';
   if (exp < 0) {
     result[index++] = '-';
     exp = -exp;
+  } else {
+    result[index++] = '+';
   }
 
   if (exp >= 100) {
@@ -413,6 +461,7 @@ static inline int to_chars(const floating_decimal_64 v, const bool sign, char* c
     memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
     index += 2;
   } else {
+    result[index++] = '0';
     result[index++] = (char) ('0' + exp);
   }
 
diff --git a/ryu/f2s.c b/ryu/f2s.c
index 255ecbe..70509d4 100644
--- a/ryu/f2s.c
+++ b/ryu/f2s.c
@@ -243,6 +243,53 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char* c
   printf("EXP=%u\n", v.exponent + olength);
 #endif
 
+  /// Plain format without exponent
+  int32_t exp = v.exponent + (int32_t) olength - 1;
+  if (exp >= -4 && exp <= 7) {
+    if (exp < 0) {
+      result[index++] = '0';
+      result[index++] = '.';
+
+      while (++exp) {
+        result[index++] = '0';
+      }
+
+      for (int32_t i = olength - 1; i >= 0; --i) {
+        const uint32_t c = output % 10;
+        output /= 10;
+        result[index + i] = '0' + c;
+      }
+      index += olength;
+    } else if (exp + 1 >= olength) {
+      for (int32_t i = olength - 1; i >= 0; --i) {
+        const uint32_t c = output % 10;
+        output /= 10;
+        result[index + i] = '0' + c;
+      }
+      index += olength;
+
+      while (exp >= olength) {
+        result[index++] = '0';
+        --exp;
+      }
+    } else {
+      for (int32_t i = olength; i > exp + 1; --i) {
+        const uint32_t c = output % 10;
+        output /= 10;
+        result[index + i] = '0' + c;
+      }
+      result[index + exp + 1] = '.';
+      for (int32_t i = exp; i >= 0; --i) {
+        const uint32_t c = output % 10;
+        output /= 10;
+        result[index + i] = '0' + c;
+      }
+      index += olength + 1;
+    }
+
+    return index;
+  }
+
   // Print the decimal digits.
   // The following code is equivalent to:
   // for (uint32_t i = 0; i < olength - 1; ++i) {
@@ -288,17 +335,19 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char* c
   }
 
   // Print the exponent.
-  result[index++] = 'E';
-  int32_t exp = v.exponent + (int32_t) olength - 1;
+  result[index++] = 'e';
   if (exp < 0) {
     result[index++] = '-';
     exp = -exp;
+  } else {
+    result[index++] = '+'; 
   }
 
   if (exp >= 10) {
     memcpy(result + index, DIGIT_TABLE + 2 * exp, 2);
     index += 2;
   } else {
+    result[index++] = '0';
     result[index++] = (char) ('0' + exp);
   }
 
